/**
 * This file is part of the CAKIS project.
 * 
 * Copyright (c) 2009-2010 - Florian Arndt, Christian Kerl
 * 
 * @license GNU Lesser General Public License v3 <http://www.opensource.org/licenses/lgpl-3.0.html>
 * @since   07.05.2010
 * @version SVN: $Id: VideoForm.java 167 2010-05-22 09:40:23Z f.aarndt@web.de $
 */
package org.cakis.client.forms;

import java.io.IOException;

import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.control.VideoControl;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreFullException;
import javax.microedition.rms.RecordStoreNotFoundException;

import org.cakis.client.AdvancedMultimediaManager;
import org.cakis.client.CakisMIDlet;
import org.cakis.client.CustomItemClass;
import org.cakis.client.MultimediaManager;
import org.cakis.client.commands.AllProductListsCommand;
import org.cakis.client.commands.HistoryCommand;
import org.cakis.client.commands.RuntimeOptionFormCommand;

/**
 * VideoForm
 * 
 * @author Florian Arndt
 */
public class VideoForm extends AbstractForm {
	private Item videoItem;
	private Player player;
	private VideoControl videoControl;
	private CakisMIDlet midlet;
	private ScannedBarcodesForm scannedForm;
	private boolean alreadyStarted = false;

	public Player getPlayer() {
		return player;
	}

	public VideoControl getVideoControl() {
		return videoControl;
	}

	public static MultimediaManager buildMultimediaManager() {
		return new AdvancedMultimediaManager();
		// Comment line above / uncomment below to make the basic version
		// return new DefaultMultimediaManager();
	}

	public VideoForm(CakisMIDlet midlet) {
		super("Camera Player", midlet);
		this.midlet = midlet;

		try {
			player = createPlayer();
			player.prefetch();
			player.realize();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (MediaException e) {
			e.printStackTrace();
		}

		this.addCommand(new HistoryCommand(midlet));
		this.addCommand(new AllProductListsCommand(midlet));
		this.addCommand(new RuntimeOptionFormCommand(midlet));
		CustomItemClass customItem = new CustomItemClass(midlet, this);
		customItem.setPreferredSize(0, 0);
		this.append(customItem);

		videoControl = (VideoControl) player.getControl("VideoControl");
		if (videoControl != null) {
			videoItem = (Item) videoControl.initDisplayMode(
					VideoControl.USE_GUI_PRIMITIVE, null);
			try {
				videoControl.setDisplaySize(this.getHeight(), this.getWidth());
			} catch (MediaException e) {
				e.printStackTrace();
			}
			videoControl.setDisplayLocation(0, 0);
			this.append(videoItem);
		} else {
			System.out.println("Error: Can not create VideoControl");
			return;
		}

		MultimediaManager multimediaManager = buildMultimediaManager();
		multimediaManager.setZoom(player);
		multimediaManager.setExposure(player);
		multimediaManager.setFlash(player);
	}

	public static Player createPlayer() throws IOException, MediaException {
		Player player = null;
		String platform = System.getProperty("microedition.platform");
		if (platform != null && platform.indexOf("Nokia") >= 0) {
			try {
				player = Manager.createPlayer("capture://image");
			} catch (MediaException me) {
			} catch (NullPointerException npe) {
			} catch (Error e) {
			}
		}
		if (player == null) {
			try {
				player = Manager.createPlayer("capture://video");
			} catch (NullPointerException npe) {
				throw new MediaException(
						"Image/video capture not supported on this phone");
			}
		}
		return player;
	}

	public void playerStart() {
		// Check if the player is started in online or offline runtime
		// OfflineHandlerFlag = false => online mode
		if (midlet.getOfflineHandler().getFlag() == false) {
			RecordStore barcodeStore;
			// Check if the RecordStore for offline scanned barcodes exist
			try {
				barcodeStore = RecordStore.openRecordStore("barcodeStore",
						false);
				// Check if there are some offline scanned barcodes,
				// ready to send to the server
				if (barcodeStore.getNumRecords() != 0) {
					barcodeStore.closeRecordStore();
					scannedForm = new ScannedBarcodesForm(midlet);
					// Check if the player already started
					if (alreadyStarted == false) {
						player.start();
						alreadyStarted = true;
					}
					scannedForm.run();
				// If there are no offline scanned barcodes, resume VideoForm
				} else {
					// Check if the player already started
					if (alreadyStarted == false) {
						try {
							player.start();
							alreadyStarted = true;
						} catch (MediaException me) {
							midlet.showError(me);
						}
					}
					midlet.display(this);
				}
			} catch (RecordStoreFullException e) {
				e.printStackTrace();
			} catch (RecordStoreNotFoundException e) {
				// If the RecordStore doesn`t exist, resume VideoForm
				// Check if the player already started
				if (alreadyStarted == false) {
					try {
						player.start();
						alreadyStarted = true;
					} catch (MediaException me) {
						midlet.showError(me);
					}
				}
				midlet.display(this);
				e.printStackTrace();
			} catch (RecordStoreException e) {
				e.printStackTrace();
			} catch (MediaException e) {
				e.printStackTrace();
			}
		// offline mode
		} else {
			// Check if the player already started
			if (alreadyStarted == false) {
				try {
					player.start();
					alreadyStarted = true;
				} catch (MediaException me) {
					midlet.showError(me);
				}
			}
			midlet.display(this);
		}
	}

	public void destroyApp() {
		if (player != null) {
			videoControl = null;
			try {
				player.stop();
			} catch (MediaException me) {
				// continue
			}
			player.deallocate();
			player.close();
			player = null;
		}
	}

	public Form getVidForm() {
		return this;
	}

	public ScannedBarcodesForm getScannedForm() {
		return scannedForm;
	}
}
